永仁與黃sir相約於天台交換情報,韓琛將於這星期進行毒品交易,地點未知。黃sir則說他費盡心力將永仁傷人的案子由坐牢改成看心理醫生,交待永仁要照做。永仁則抱怨自己被黃sir騙了,說好只當三年臥底,結果現在都快十年了,不知道何時才能恢復警察身份。十年間發生了太多事,永仁看著黃sir送的手錶,他有時候真的不知道該用什麼心態面對黃sir(詳情請見無間道Ⅱ及無間道Ⅲ)。
insert
此場景時間2002年insert FuzzyTime {fuzzy_year:= 2002};
alias
及編寫測試alias
的function
建立一個year_2002
(2002年)的alias
。
alias year_2002:= assert_exists(assert_single((select FuzzyTime
filter .fuzzy_year = 2002
and .fuzzy_month ?= <FuzzyMonth>{}
and .fuzzy_day ?= <FuzzyDay>{}
and .fuzzy_hour ?= <FuzzyHour>{}
and .fuzzy_minute ?= <FuzzyMinute>{}
and .fuzzy_second ?= <FuzzySecond>{}
and .fuzzy_dow ?= <DayOfWeek>{}
))
);
新增test_scene05_alias()
並更新test_alias()
。
function test_alias() -> bool
using (all({
test_scene01_alias(),
test_scene02_alias(),
test_scene03_alias(),
test_scene05_alias(),
})
);
function test_scene05_alias() -> bool
using (all({
(exists year_1994),
})
);
did you create alias 'default::year_2002'? [y,n,l,c,b,s,q,?]
> y
did you create function 'default::test_scene05_alias'? [y,n,l,c,b,s,q,?]
> y
did you alter function 'default::test_alias'? [y,n,l,c,b,s,q,?]
> y
test_alias()
# end migration needs to be applied before running this query
select test_alias();
update
chen
這裡永仁連說了兩句經典台詞,讓我們把它們都加在classic_lines property
中(留意這邊使用的語法是classic_lines := .classic_lines ++ array<str>
)。
update chen
set {
classic_lines := .classic_lines ++
["你話三年。三年之後又三年,三年之後又三年!十年都嚟緊頭啦老細!",
"收嗲啦!呢句嘢我聽咗九千幾次啦!"],
};
datetime
的模糊加減法假如我們想幫永仁算一下他所說的「三年之後又三年,三年之後又三年!十年都嚟緊頭啦」,大概是多久的話,可以使用cal::relative_duration()
。
我們假設永仁從1992年12月1日0時0分0秒,正式開始臥底工作。
首先我們需要將這個時間轉換為datetime
型態。您可以選擇使用<datetime>
來casting
或是使用to_datetime()
來轉換。
初學EdgeDB的朋友可能會搞混這兩個方法。此時可以查看datetime
文件,
通常沒有()
的像是datetime
或是cal::local_datetime
,這代表是一種型態,可以於其後加上適當的str
來casting
。
而像是有to
開頭且有()
的to_datetime()
或是cal::to_local_datetime()
,則代表function
,需要參考其所提供的各種簽名來使用。EdgeDB可以針對同一個function
名定義多次,接收不同的參數,像是to_datetime()
就提供六種可以呼叫的簽名,這種特性稱為function overloaded
。
下面四種query皆會產生同樣的結果:
select <datetime>"1992-12-01T00:00:00+08";
select to_datetime("1992-12-01T00:00:00+08");
select to_datetime(1992, 12, 1, 0, 0, 0, "Asia/hong_kong");
select to_datetime(
<cal::local_datetime>"1992-12-01T00:00:00",
"Asia/hong_kong"
);
{<datetime>'1992-11-30T16:00:00Z'}
接下來利用cal::relative_duration
來casting
一個接近十年時間的str
,假設為9年10個月。沒錯,cal::relative_duration
可以接受像9 years 10 months
這麼人性化的輸入!
select <cal::relative_duration>"9 years 10 months";
{<cal::relative_duration>'P9Y10M'}
接著我們將1992年12月1日0時0分0秒的datetime
加上9年10個月的relative_duration
:
select <datetime>"1992-12-01T00:00:00+08" +
<cal::relative_duration>"9 years 10 months";
{<datetime>'2002-09-30T16:00:00Z'}
最後將結果的datetime
型態轉變為local_datetime
型態:
with t:=(select <datetime>"1992-12-01T00:00:00+08" +
<cal::relative_duration>"9 years 10 months")
select cal::to_local_datetime(t, "Asia/hong_kong");
{<cal::local_datetime>'2002-10-01T00:00:00'}
現在我們終於知道永仁與黃sir於本場景見面的時間,大概為2002年10月,這個計算大致符合劇中的時間線。
local_datetime
的模糊加減法datetime
的計算看起來比較複雜,因為牽扯到timezone
。如果您想要計算的是local_datetime
的話,那麼可以輕鬆不少。
select <cal::local_datetime>"1992-12-01T00:00:00" +
<cal::relative_duration>"9 years 10 months";
{<cal::local_datetime>'2002-10-01T00:00:00'}
update
wong
將黃sir的經典台詞指定給classic_lines
property
(留意這邊使用的是:=
)。
update wong
set {
classic_lines := ["你25號生日嘛!25仔!"],
};
25仔在粵語中即為「反骨仔」或「臥底」之意。黃sir此舉乃是在嘲諷永仁。
local_date
的模糊加減法假設黃sir想幫永仁算一下,離永仁25號生日還有幾天,可以使用cal::local_date
這麼算:
select <cal::local_date>"2002-10-25" - <cal::local_date>"2002-10-01";
{<cal::date_duration>'P24D'}
可以得知,大概還有24天(永仁於劇末的墓碑出生日期為1966年10月25日)。
insert
此場景的Scene
insert Scene {
title:= "三年之後又三年",
detail:= "永仁與黃sir相約於天台交換情報,韓琛將於這星期進行毒品" ++
"交易,地點未知。黃sir則說他費盡心力將永仁傷人的案子由" ++
"坐牢改成看心理醫生,交待永仁要照做。永仁抱怨自己被黃sir" ++
"騙了,說好只當三年臥底,結果現在都快十年了,不知道何時才" ++
"能恢復警察身份。十年間發生了太多事,永仁看著黃sir送的手錶" ++
",他有時候真的不知道該用什麼心態面對黃sir(詳情請見無間道Ⅱ" ++
"及無間道Ⅲ)。",
who:= {wong, chen},
`when`:= year_2002,
where:= (insert Location {name:="天台"}),
};
有一種說法是黃sir特別喜歡送人手錶。除了於天台送了永仁手錶外,無間道Ⅱ中Mary姐的手錶也是黃sir所送。所以當建明詢問Mary姐其所戴手錶是否為韓琛所送,她並沒有正面回應。